package judesart.app.client.gallery.ui;

import java.util.ArrayList;
import java.util.List;

import judesart.app.client.gallery.GalleryController;
import judesart.app.client.gallery.GalleryControllerAsync;
import judesart.app.client.layout.MainLayout;
import judesart.app.client.widget.TopInfo;
import judesart.app.domain.Gallery;
import judesart.app.domain.Room;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.MemoryProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;

public class GalleryDetailsPanel extends Composite
{
    GalleryControllerAsync service = GalleryController.Util.getInstance();
    private Gallery gallery;
    private final TextField<String> txtfldName;
    private final TextArea txtrDescription;
    private final Button btnAddRoom;
    private final Button btnSave;
    private final Button btnDelete;
    private final HorizontalPanel galleryDetailsPanel;
    private final RoomDetailsPanel roomDetails;
    private final ContentPanel cntntpnlGallery;
    private final List<Room> rooms = new ArrayList<Room>();
    private final ListLoader<ListLoadResult<Room>> loader;

    public GalleryDetailsPanel()
    {
        setBorders(false);
        cntntpnlGallery = new ContentPanel();
        cntntpnlGallery.setHeading("Gallery");

        MemoryProxy<List<Room>> proxy = new MemoryProxy<List<Room>>(rooms);
        loader = new BaseListLoader<ListLoadResult<Room>>(proxy,
                new BeanModelReader());
        ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
        loader.load();

        galleryDetailsPanel = new HorizontalPanel();

        FormPanel formPanel = new FormPanel();
        formPanel.setLabelSeparator("");
        formPanel.setLabelAlign(LabelAlign.TOP);
        formPanel.setHeaderVisible(false);
        formPanel.setBorders(false);
        formPanel.setBodyBorder(false);

        txtfldName = new TextField<String>();
        formPanel.add(txtfldName, new FormData("100%"));
        txtfldName.setFieldLabel("Name");

        txtrDescription = new TextArea();
        txtrDescription.setHeight("164px");
        formPanel.add(txtrDescription, new FormData("100%"));
        txtrDescription.setFieldLabel("Description");

        ButtonBar buttons = new ButtonBar();
        buttons.setAlignment(HorizontalAlignment.RIGHT);
        buttons.setMinButtonWidth(80);
        btnAddRoom = new Button("Add Room");
        btnAddRoom.addListener(Events.Select, new Listener<ButtonEvent>()
        {
            public void handleEvent(ButtonEvent e)
            {
                addRoom();
            }
        });
        buttons.add(btnAddRoom);

        btnSave = new Button("Save");
        btnSave.addListener(Events.Select, new Listener<ButtonEvent>()
        {
            public void handleEvent(ButtonEvent e)
            {
                save();
            }
        });
        buttons.add(btnSave);

        btnDelete = new Button("Delete");
        btnDelete.addListener(Events.Select, new Listener<ButtonEvent>()
        {
            public void handleEvent(ButtonEvent e)
            {
                delete();
            }
        });
        buttons.add(btnDelete);
        galleryDetailsPanel.add(formPanel);
        formPanel.setSize("277px", "490px");

        VerticalPanel verticalPanel = new VerticalPanel();
        verticalPanel.setHeight("395px");

        final ListView<BeanModel> roomsListView = new ListView<BeanModel>(store)
        {
            @Override
            protected BeanModel prepareData(BeanModel model)
            {
                Room room = model.getBean();
                if (room.getArtworks() != null && room.getArtworks().size() > 0)
                {
                    model.set("mainImageId",
                            room.getArtworks().get(0).getMainImageId());
                }
                return model;
            }
        };
        roomsListView.setLoadingText("loading...");
        roomsListView.setBorders(false);
        roomsListView.setSize("479px", "456px");
        roomsListView.setTemplate(getTemplate());
        roomsListView.setItemSelector("div.thumb-wrap");
        roomsListView.getSelectionModel().addListener(Events.SelectionChange,
                new Listener<SelectionChangedEvent<BeanModel>>()
                {
                    public void handleEvent(SelectionChangedEvent<BeanModel> be)
                    {
                        onSelectionChanged(be);
                    }
                });

        verticalPanel.add(roomsListView);
        verticalPanel.add(buttons);
        galleryDetailsPanel.add(verticalPanel);
        cntntpnlGallery.add(galleryDetailsPanel);
        roomDetails = new RoomDetailsPanel(this);
        roomDetails.setVisible(false);
        cntntpnlGallery.add(roomDetails);
        initComponent(cntntpnlGallery);
        cntntpnlGallery.setSize("800px", "513px");
    }

    private void save()
    {
        gallery.setTitle(txtfldName.getValue());
        gallery.setDescription(txtrDescription.getValue());
        if (gallery.getId() == null)
        {
            createGalleryAsync();
        } else
        {
            updateGalleryAsync();
        }
    }

    private void createGalleryAsync()
    {
        service.createGallery(gallery, new AsyncCallback<Gallery>()
        {
            @Override
            public void onFailure(Throwable caught)
            {
                Log.error("Unable to create gallery", caught);
                TopInfo.display("Error", "Unable to create Gallery");
            }

            @Override
            public void onSuccess(Gallery result)
            {
                TopInfo.display("Info", "Gallery created");
                gallery = result;
                showDetails();
                MainLayout.getInstance().refreshMenu();
            }
        });
    }

    private void updateGalleryAsync()
    {
        service.updateGallery(gallery, new AsyncCallback<Gallery>()
        {
            @Override
            public void onFailure(Throwable caught)
            {
                Log.error("Unable to update gallery", caught);
                TopInfo.display("Error", "Unable to create Gallery");
            }

            @Override
            public void onSuccess(Gallery result)
            {
                TopInfo.display("Info", "Gallery updated");
                gallery = result;
                showDetails();
                MainLayout.getInstance().refreshMenu();
            }
        });
    }

    private void delete()
    {
        service.deleteGallery(gallery.getId(), new AsyncCallback<Void>()
        {
            @Override
            public void onFailure(Throwable caught)
            {
                TopInfo.display("Error", "Unable to delete gallery");
                Log.error("Unable to delete gallery", caught);
            }

            @Override
            public void onSuccess(Void result)
            {
                TopInfo.display("Info", "Gallery deleted");
                MainLayout.getInstance().refreshMenu();
                MainLayout.getInstance().menuClicked("galleries");
            }
        });
    }

    private void addRoom()
    {
        roomDetails.open(null);
        showRoom();
    }

    protected void showGallery()
    {
        galleryDetailsPanel.setVisible(true);
        roomDetails.setVisible(false);
        cntntpnlGallery.setHeading("Gallery");
        showDetails();
        cntntpnlGallery.layout();
    }

    protected void openRoom(Room room)
    {
        roomDetails.open(room);
        showRoom();
    }

    private void showRoom()
    {
        galleryDetailsPanel.setVisible(false);
        roomDetails.setVisible(true);
        cntntpnlGallery.setHeading("Gallery - Room");
        cntntpnlGallery.layout();
    }

    public void open(Gallery gallery)
    {
        this.gallery = gallery;
        showDetails();
    }

    public void open(Long galleryId)
    {

        if (galleryId == null)
        {
            open(new Gallery());
        } else
        {
            service.getGallery(galleryId, new AsyncCallback<Gallery>()
            {

                @Override
                public void onSuccess(Gallery result)
                {
                    open(result);
                }

                @Override
                public void onFailure(Throwable caught)
                {
                }
            });
        }
    }

    protected Gallery getGallery()
    {
        return this.gallery;
    }

    private void showDetails()
    {
        if (gallery == null)
        {
            gallery = new Gallery();
        }

        boolean isNew = gallery.getId() == null;
        if (isNew)
        {
            btnAddRoom.setEnabled(false);
            btnDelete.setEnabled(false);
        } else
        {
            btnAddRoom.setEnabled(true);
            btnDelete.setEnabled(true);
        }
        txtfldName.setValue(gallery.getTitle());
        txtrDescription.setValue(gallery.getDescription());
        rooms.clear();
        if (gallery.getRooms() != null)
        {
            rooms.addAll(gallery.getRooms());
        }
        loader.load();
    }

    private native String getTemplate() /*-{
        return ['<tpl for=".">', 
        '<div style="border: 1px solid #FFFFFF;float:left;margin:4px 0 4px  4px; padding:2px;width:100px; height: 100px;" class="thumb-wrap" id="{mainImageId}">', 
        '<div style="width: 240px;" class="thumb"><img src="/image?id={mainImageId}&size=100x100&crop=true"></div>', 
        '<div style="width: 100%; text-align: center; color: #999999;">{name}</div>',
        '</div>',
        '</tpl>', 
        '<div class="x-clear"></div>'].join("");
    }-*/;

    private void onSelectionChanged(SelectionChangedEvent<BeanModel> be)
    {
        Object source = be.getSource();
        Log.debug("source [" + source + "]");
        if (be.getSelection().size() == 0)
        {
            return;
        }
        final BeanModel model = be.getSelection().get(0);
        Room room = model.getBean();
        openRoom(room);
    }
}
